package com.sakila.action.member;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sakila.action.BaseAction;
import com.sakila.action.util.JsonUtil;
import com.sakila.pojo.Member;
import com.sakila.pojo.other.Page;
import com.sakila.service.CityService;
import com.sakila.service.MemberService;
import com.sakila.service.StoreService;
import com.sakila.vo.MemberVo;

@Controller
@RequestMapping("/staff")
public class StaffMemberAction implements BaseAction {
	private static final Logger logger = LoggerFactory.getLogger(StaffMemberAction.class);
	
	@Resource
	private StoreService storeService;
	@Resource
	private CityService cityService;
	@Resource
	private MemberService memberService;
	
	@RequestMapping(value="/goto_memberManage")
	public String viewMemberByStaff(Model model){
		return "staff/member/index";
	}
	
	@RequestMapping(value="/goto_modifyMember/{memberId}")
	public String viewModifyMember(Model model, @PathVariable Integer memberId){
		Member member = memberService.findByCustomerId(memberId);
		this.setModelAndView(model, member);
		return "member/modify";
	}
	
	@RequestMapping(value="/viewMember")
	@ResponseBody
	public Object viewMembers(@RequestParam(value=PAGE_ID, defaultValue="1") Integer pageId,
							  @RequestParam(value=PAGE_SIZE, defaultValue="20") Integer pageSize,
							  @RequestParam(value="memberId", required=false)Integer customerId){
		MemberVo mv;
		if(customerId != null){
			mv = memberService.findByCustomerIdReturnVo(customerId);
		}else {
			mv = memberService.findAll(new Page(pageId, pageSize));
		}
		return JsonUtil.toJson(mv.getList(), mv.getTotalNumOfRows());
	}
	
	@RequestMapping(value="/modifyMember")
	public String modify(Model model, @Valid Member member, Errors errors){
		if(errors.hasErrors()){
			logger.debug(">>>>>>>>>>>>>>>>>Error occur: modify member.");
			
			//Be careful, the request must contain the actual validated object not creating a new one.
			this.setModelAndView(model, member);
			return "member/modify";
		}
		
		boolean modifiedPassword = false;
		if(member.getPassword() != null){
			logger.debug(">>>>>>>>>>>>>>>>>Modify member: new password set.");
			BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(16);
			String cryptedPwd = passwordEncoder.encode(new StringBuilder(member.getPassword()));
			member.setPassword(cryptedPwd);
			modifiedPassword = true;
		}
		memberService.update(member);
		if(modifiedPassword){
			SecurityContextHolder.getContext().setAuthentication(null);
		}
		return "redirect:/staff/goto_memberManage";
	}
	
	private void setModelAndView(Model model, Member member){
		model.addAttribute("member", member);
		model.addAttribute("stores", storeService.findAll());
		model.addAttribute("cities", cityService.findAll());
	}
}
